iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Software Development

戀戀 Elixir系列 第 17

十七. Keyword Lists

  • 分享至 

  • xImage
  •  

You are the manager of a fancy restaurant that has a sizable wine cellar. A lot of your customers are demanding wine enthusiasts.

Finding the right bottle of wine for a particular customer is not an easy task.
As a tech-savvy restaurant owner, you decided to speed up the wine selection process by writing an app that will let guests filter your wines by their preferences.

1. Explain wine colors

On the welcome screen of your app, you want to display a short explanation of each wine color.

Implement the WineCellar.explain_colors/0 function. It takes no arguments and returns a keyword list with wine colors as keys and explanations as values.

2. Get all wines of a given color

A bottle of wine is represented as a 3-tuple of grape variety, year, and country of origin. The wines are stored by wine color in a keyword list.

Implement the WineCellar.filter/3 function. It should take a keyword list of wines, a color atom and a keyword list of options, with a default value of []. The function should return a list of wines of a given color.

3. Get all wines of a given color bottled in a given year

Extend the WineCellar.filter/3 function. When given a :year option, the function should return a list of wines of a given color from a given year.

Use the already-implemented WineCellar.filter_by_year/2 function. It takes a list of wines and a year as arguments and returns a list of wines from a given year.

4. Get all wines of a given color bottled in a given country

Extend the WineCellar.filter/3 function. When given a :country option, the function should return a list of wines of a given color from a given country.

Use the already-implemented WineCellar.filter_by_country/2 function. It takes a list of wines and a country as arguments and returns a list of wines from a given country.

Make sure that the function works when given both the :year and the :country option, in any order.


https://exercism.org/tracks/elixir/exercises/wine-cellar

defmodule WineCellar do
  @moduledoc """
  practice keyword lists
  """

  @doc """
  show the colors keyword lists
  """
  @spec explain_colors :: keyword(String.t())
  def explain_colors do
    [
      white: "Fermented without skin contact.",
      red: "Fermented with skin contact using dark-colored grapes.",
      rose: "Fermented with some skin contact, but not enough to qualify as a red wine.",
    ]
  end

  @doc """
  filter keyword lists
  """
  @spec filter(cellar :: keyword(tuple()), color :: atom(), opts :: keyword(number)) :: [tuple()]
  def filter(cellar, color, opts \\ []) do
    Keyword.get_values(cellar, color)
    |> filter_by_year(opts[:year])
    |> filter_by_country(opts[:country])
  end
  
  # def filter(cellar, color, opts \\ []) do
  #   year = opts[:year]
  #   country = opts[:country]

  #   wines = Keyword.get_values(cellar, color)
  #   wines = if (year), do: filter_by_year(wines, year), else: wines
  #   if (country), do: filter_by_country(wines, country), else: wines
  # end

  # The functions below do not need to be modified.

  defp filter_by_year(wines, nil), do: wines
  defp filter_by_year([], _year), do: []
  defp filter_by_year([{_, year, _} = wine | tail], year) do
    [wine | filter_by_year(tail, year)]
  end

  defp filter_by_year([{_, _, _} | tail], year) do
    filter_by_year(tail, year)
  end

  defp filter_by_country(wines, nil), do: wines
  defp filter_by_country([], _country), do: []
  defp filter_by_country([{_, _, country} = wine | tail], country) do
    [wine | filter_by_country(tail, country)]
  end
  defp filter_by_country([{_, _, _} | tail], country) do
    filter_by_country(tail, country)
  end
end

上一篇
十六. Processes
下一篇
十八. Bistrings
系列文
戀戀 Elixir30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言